﻿using System;
using System.Collections.Generic;
using UnityEngine;

namespace UFrame
{
    public class EventStrMa
    {
        private EventStrMa()
        {
        }

        private static Dictionary<string, Delegate> eventMap = new Dictionary<string, Delegate>();


        #region 事件

        public static void Register(string id, Action eventHandle)
        {
            Register(id, (Delegate) eventHandle);
        }

        public static void Register<T>(string id, Action<T> eventHandle)
        {
            Register(id, (Delegate) eventHandle);
        }

        public static void Register<T, T2>(string id, Action<T, T2> eventHandle)
        {
            Register(id, (Delegate) eventHandle);
        }

        public static void Register<T, T2, T3>(string id, Action<T, T2, T3> eventHandle)
        {
            Register(id, (Delegate) eventHandle);
        }

        public static void Register<T, T2, T3, T4>(string id, Action<T, T2, T3, T4> eventHandle)
        {
            Register(id, (Delegate) eventHandle);
        }

        public static void Register(string id, Delegate eventHandle)
        {
            if (!eventMap.ContainsKey(id))
            {
                eventMap[id] = eventHandle;
            }
            else
            {
                try
                {
                    eventMap[id] = Delegate.Combine(eventMap[id], eventHandle);
                }
                catch
                {
                    Debug.LogError("AddEvent == null, id is " + id.ToString());
                }
            }
        }


        private static void NotifyMain(string id, params object[] args)
        {
            if (eventMap.ContainsKey(id))
            {
                Delegate gata = eventMap[id];
                if (gata == null)
                {
                    return;
                }

                Delegate[] gateList = gata.GetInvocationList();
                int count = gateList.Length;
                for (int i = 0; i < count; i++)
                {
                    string str = gateList[i].Target.ToString();
                    if (str == "null")
                    {
                        eventMap[id] = gata = Delegate.Remove(gata, gateList[i]);
                        Debug.LogWarning("gateList[i].Target == null, id is " + id.ToString());
                        continue;
                    }

                    gateList[i].DynamicInvoke(args);
                }
            }
        }

        public static void Notify(string id)
        {
            NotifyMain(id);
        }

        public static void Notify<T>(string id, T arg1)
        {
            NotifyMain(id, arg1);
        }

        public static void Notify<T, U>(string id, T arg1, U arg2)
        {
            NotifyMain(id, arg1, arg2);
        }

        public static void Notify<T, U, V>(string id, T arg1, U arg2, V arg3)
        {
            NotifyMain(id, arg1, arg2, arg3);
        }

        public static void Notify<T, U, V, W>(string id, T arg1, U arg2, V arg3, W arg4)
        {
            NotifyMain(id, arg1, arg2, arg3, arg4);
        }

        public static void UnregisterMain(string id, Delegate eventHandle)
        {
            Delegate gate = null;
            if (eventMap.TryGetValue(id, out gate))
            {
                eventMap[id] = Delegate.Remove(gate, eventHandle);
            }
        }

        public static void Unregister(string id, Action eventHandle)
        {
            UnregisterMain(id, eventHandle);
        }

        public static void Unregister<T>(string id, Action<T> eventHandle)
        {
            UnregisterMain(id, eventHandle);
        }

        public static void Unregister<T, U>(string id, Action<T, U> eventHandle)
        {
            UnregisterMain(id, eventHandle);
        }

        public static void Unregister<T, U, V>(string id, Action<T, U, V> eventHandle)
        {
            UnregisterMain(id, eventHandle);
        }

        public static void Unregister<T, U, V, W>(string id, Action<T, U, V, W> eventHandle)
        {
            UnregisterMain(id, eventHandle);
        }

        public void Clear()
        {
            eventMap.Clear();
        }

        #endregion
    }
}